package PruebasUnitarias;

import java.util.*;

import junit.framework.TestCase;
import Modelo.*;

public class MapaTest extends TestCase {
	private Bloque[][] bloques;	
	private Bloque b1;
	private Bloque b2;
	private Bloque b3;
	private Bloque b4;
	private Bloque b5;
	private Bloque b6;
	private Bloque b7;
	private Mapa mapa;
	
	/*       y
	O-------->
	|                	F	V	V	V	H
	|					H 	H	H	H	H								
	|					V	F	NL	F	N
	|					R	R	R	R	R
	V x					T	T	T	T	R
						
	*/
	protected void setUp() throws Exception {
		super.setUp();
		mapa= new Mapa(); 
		bloques= new Bloque[5][5];
		b1= new Fuego(mapa);
		b2= new Hielo(mapa);
		b3= new Vacio(mapa);
		b4= new NaveEspacialLlegada(mapa);
		b5= new Tierra(mapa);
		b6= new Roca(mapa);
		b7= new Vacio(mapa);
		bloques[0][0]=b1;
		bloques[0][4]=b2;
		bloques[2][0]=b3;
		bloques[2][4]=b4;
		bloques[4][0]=b5;
		bloques[4][4]=b6;
		bloques[2][2]=b7;
		for(int i=1;i<4;i++)
			bloques[0][i]= new Vacio(mapa);
		for(int i=0;i<5;i++)
			bloques[1][i]= new Hielo(mapa);
		for(int i=0;i<5;i++)
			bloques[3][i]= new Roca(mapa);
		for(int i=1;i<4;i++)
			bloques[4][i]= new Tierra(mapa);
		bloques[2][1]= new Fuego(mapa);
		bloques[2][3]= new Fuego(mapa);
		mapa.inicializarMapa(bloques);
	}
	
	private void nuevoMapa(){
/*		
	 	T	T	T	N	T	T							_
		T	T	T	V	T	T							|
		T	V	V	V	V	T						  --|==>
		T	V	T	N	T	T						 |	
		T	NL	T	N	T	T						 -
		T	F	T	N	T	T	
		T	T	T	N	T	T			
		
*/
		mapa= null;
		bloques= null;
		bloques= new Bloque[7][7];
		mapa= new Mapa();
		for(int i=0;i<7;i++)
			for(int j=0;j<7;j++)
				bloques[i][j]= new Tierra(mapa);
		for(int i=1;i<6;i++)
			bloques[2][i]= new Vacio(mapa);
		bloques[1][3]= new NaveEspacial(mapa);
		bloques[3][1]= new Vacio(mapa);
		bloques[4][1]= new NaveEspacialLlegada(mapa);
		bloques[5][1]= new Fuego(mapa);
		mapa.inicializarMapa(bloques);
	}
	
	private void nuevoMapa2(){
		/*		
			 	T	T	T	N	T	T							_
				T	T	T	V	T	T							|
				T	V	V	V	V	T						  --|==>
				T	V	T	N	T	T						 |	
				T	NL	T	N	T	T						 -
				T	F	T	N	T	T	
				T	T	T	N	T	T			
				
		*/
				mapa= null;
				bloques= null;
				bloques= new Bloque[7][7];
				mapa= new Mapa();
				for(int i=0;i<7;i++)
					for(int j=0;j<7;j++)
						bloques[i][j]= new Tierra(mapa);
				for(int i=1;i<6;i++)
					bloques[2][i]= new Vacio(mapa);
				bloques[1][3]= new NaveEspacial(mapa);
				bloques[3][1]= new Vacio(mapa);
				bloques[5][1]= new NaveEspacialLlegada(mapa);
				bloques[4][1]= new AgujeroNegro(mapa);
				mapa.inicializarMapa(bloques);
			}
	
	public void testNaveTransbordo(){
		assertTrue(mapa.naveTransbordo()==b4);
		assertTrue(mapa.naveTransbordo()==bloques[2][4]);
	}
	
	public void testGetbloquesANDistanciaDe(){
		ArrayList<Bloque> lista;
		
		lista=(ArrayList<Bloque>) mapa.getbloquesANDistanciaDe(b1, 1);
		assertTrue(lista.size()==3);
		assertTrue(lista.get(0)==bloques[0][1]);
		assertTrue(lista.get(1)==bloques[1][0]);
		assertTrue(lista.get(2)==bloques[1][1]);
		
		lista=(ArrayList<Bloque>) mapa.getbloquesANDistanciaDe(b2, 1);
		assertTrue(lista.size()==3);
		assertTrue(lista.get(0)==bloques[0][3]);
		assertTrue(lista.get(1)==bloques[1][3]);
		assertTrue(lista.get(2)==bloques[1][4]);
		
		lista=(ArrayList<Bloque>) mapa.getbloquesANDistanciaDe(b3, 1);
		assertTrue(lista.size()==5);
		assertTrue(lista.get(0)==bloques[1][0]);
		assertTrue(lista.get(1)==bloques[1][1]);
		assertTrue(lista.get(2)==bloques[2][1]);
		assertTrue(lista.get(3)==bloques[3][0]);
		assertTrue(lista.get(4)==bloques[3][1]);
		
		lista=(ArrayList<Bloque>) mapa.getbloquesANDistanciaDe(b4, 1);
		assertTrue(lista.size()==5);
		assertTrue(lista.get(0)==bloques[1][3]);
		assertTrue(lista.get(1)==bloques[1][4]);
		assertTrue(lista.get(2)==bloques[2][3]);
		assertTrue(lista.get(3)==bloques[3][3]);
		assertTrue(lista.get(4)==bloques[3][4]);
		
		lista=(ArrayList<Bloque>) mapa.getbloquesANDistanciaDe(b5, 1);
		assertTrue(lista.size()==3);
		assertTrue(lista.get(0)==bloques[3][0]);
		assertTrue(lista.get(1)==bloques[3][1]);
		assertTrue(lista.get(2)==bloques[4][1]);
		
		lista=(ArrayList<Bloque>) mapa.getbloquesANDistanciaDe(b6, 1);
		assertTrue(lista.size()==3);
		assertTrue(lista.get(0)==bloques[3][3]);
		assertTrue(lista.get(1)==bloques[3][4]);
		assertTrue(lista.get(2)==bloques[4][3]);
		
		lista=(ArrayList<Bloque>) mapa.getbloquesANDistanciaDe(b7, 1);
		assertTrue(lista.size()==8);
		assertTrue(lista.get(0)==bloques[1][1]);
		assertTrue(lista.get(1)==bloques[1][2]);
		assertTrue(lista.get(2)==bloques[1][3]);
		assertTrue(lista.get(3)==bloques[2][1]);
		assertTrue(lista.get(4)==bloques[2][3]);
		assertTrue(lista.get(5)==bloques[3][1]);
		assertTrue(lista.get(6)==bloques[3][2]);
		assertTrue(lista.get(7)==bloques[3][3]);
	}
	
	public void testGetBloqueDondeEsta(){
		Personaje pooglin= new Pooglin(mapa);
		// el hielo no aloja
		bloques[1][2].alojar(pooglin);
		assertFalse(mapa.getBloqueDondeEsta(pooglin)==bloques[1][2]);
		bloques[1][2].desalojar(pooglin);
		// el vacio aloja
		bloques[0][2].alojar(pooglin);
		assertTrue(mapa.getBloqueDondeEsta(pooglin)==bloques[0][2]);
		bloques[0][2].desalojar(pooglin);
		// el fuego no aloja
		assertTrue(pooglin.estaVivo());	// de paso verifico que este vivo
		bloques[2][1].alojar(pooglin);	
		assertFalse(mapa.getBloqueDondeEsta(pooglin)==bloques[2][1]);
		assertFalse(pooglin.estaVivo());	// de paso verifico que haya muerto
		bloques[2][1].desalojar(pooglin);	
		// la roca no aloja
		bloques[3][2].alojar(pooglin);
		assertFalse(mapa.getBloqueDondeEsta(pooglin)==bloques[3][2]);
		bloques[3][2].desalojar(pooglin);
		// la tierra no aloja
		bloques[4][2].alojar(pooglin);
		assertFalse(mapa.getBloqueDondeEsta(pooglin)==bloques[4][2]);
	}
	
	public void testGetBloqueNEnDireccionDesdeUbicacionDe(){
		Personaje pooglin= new Pooglin(mapa);
		b7.alojar(pooglin);
		assertTrue(mapa.getBloqueNEnDireccionDesdeUbicacionDe(pooglin,1,Constantes.derecha)==bloques[2][3]);
		assertTrue(mapa.getBloqueNEnDireccionDesdeUbicacionDe(pooglin,2,Constantes.izquierda)==bloques[2][0]);
		assertTrue(mapa.getBloqueNEnDireccionDesdeUbicacionDe(pooglin,2,Constantes.arriba)==bloques[0][2]);
		assertTrue(mapa.getBloqueNEnDireccionDesdeUbicacionDe(pooglin,1,Constantes.abajo)==bloques[3][2]);
		assertTrue(mapa.getBloqueNEnDireccionDesdeUbicacionDe(pooglin,1,Constantes.arriba,2,Constantes.derecha)==bloques[1][4]);
		assertTrue(mapa.getBloqueNEnDireccionDesdeUbicacionDe(pooglin,2,Constantes.abajo,1,Constantes.derecha)==bloques[4][3]);
		assertTrue(mapa.getBloqueNEnDireccionDesdeUbicacionDe(pooglin,2,Constantes.arriba,1,Constantes.izquierda)==bloques[0][1]);
	}
	
	public void testModificarBloquePor(){
		mapa.ModificarBloquePor(b3, new Tierra(mapa));
		Personaje pooglin= new Pooglin(mapa);
		b7.alojar(pooglin);
		assertFalse(bloques[2][0] instanceof Vacio);
		assertTrue(bloques[2][0] instanceof Tierra);
	}
	
	public void testGeneralLlegada(){
		nuevoMapa();
		// Cae, camina, choca, camina, cae, llega
		Personaje pooglin= new Pooglin(mapa);
		Thread elPooglin= (Thread) pooglin;
		mapa.Agregar(pooglin);
		while(elPooglin.isAlive());
		assertTrue(pooglin.estaVivo());
		assertTrue(mapa.naveTransbordo().estaAlojado(pooglin));
	}	
	
	public void testGeneralMuerteQuemadura(){
		nuevoMapa();
		bloques[4][1]= new Fuego(mapa);
		// Cae, camina, choca, camina, cae, muere
		Personaje pooglin= new Pooglin(mapa);
		Thread elPooglin= (Thread) pooglin;
		mapa.Agregar(pooglin);
		while(elPooglin.isAlive());
		assertFalse(pooglin.estaVivo());
	}	
	
	public void testGeneralMuerteAgujeroNegro(){
		nuevoMapa2();
		// Cae, camina, choca, camina, cae, muere
		Personaje pooglin= new Pooglin(mapa);
		Thread elPooglin= (Thread) pooglin;
		mapa.Agregar(pooglin);
		while(elPooglin.isAlive());
		assertFalse(pooglin.estaVivo());
	}	
	
}
